#include <gtest/gtest.h>
#include <sys/epoll.h>
#include "channel.h"
#include "eventloop.h"

class MockEventLoop : public EventLoop {
public:
    int updateCalled = 0;
    int removeCalled = 0;

    void updateChannel(Channel* ch) override {
        updateCalled++;
    }
    void removeChannel(Channel* ch) override {
        removeCalled++;
    }
};

TEST(ChannelTest, CallbacksTriggerCorrectly) {
    MockEventLoop loop;
    Channel channel(&loop, 10);

    bool readCalled = false;
    bool writeCalled = false;
    bool closeCalled = false;
    bool errorCalled = false;

    channel.setReadCallback([&]() { readCalled = true; });
    channel.setWriteCallback([&]() { writeCalled = true; });
    channel.setCloseCallback([&]() { closeCalled = true; });
    channel.setErrorCallback([&]() { errorCalled = true; });

    // 模拟事件发生
    channel.set_revents(EPOLLIN);
    channel.handleEvent();
    EXPECT_TRUE(readCalled);

    // 重置
    readCalled = false;

    channel.set_revents(EPOLLOUT);
    channel.handleEvent();
    EXPECT_TRUE(writeCalled);

    channel.set_revents(EPOLLHUP);
    channel.handleEvent();
    EXPECT_TRUE(closeCalled);

    channel.set_revents(EPOLLERR);
    channel.handleEvent();
    EXPECT_TRUE(errorCalled);
}

TEST(ChannelTest, EnableDisableCallsUpdate) {
    int fds[2];
    ASSERT_EQ(pipe(fds), 0);

    MockEventLoop loop;
    Channel channel(&loop, fds[0]);

    EXPECT_EQ(loop.updateCalled, 0);

    channel.enableReading();
    EXPECT_EQ(loop.updateCalled, 1);

    channel.disableAll();
    EXPECT_EQ(loop.updateCalled, 2);

    close(fds[0]);
    close(fds[1]);
}

TEST(ChannelTest, RemoveCallsRemoveChannel) {
    int fds[2];
    ASSERT_EQ(pipe(fds), 0);

    MockEventLoop loop;
    Channel channel(&loop, fds[0]);

    EXPECT_EQ(loop.removeCalled, 0);
    channel.remove();
    EXPECT_EQ(loop.removeCalled, 1);

    close(fds[0]);
    close(fds[1]);
}

